
var net = require('net');
var logger = require('./logger');

if (!process.argv[2]) {
	// Handle possible error for the input at running the server
	throw "Undefined port";
}

logger.log('info', 'Initializing server at port: ' + process.argv[2]);

var server = net.createServer(function (socket) {
    logger.log('info', 'Client connected (ip,port) (' + socket.remoteAddress + ' , '+ socket.remotePort  + ')');
    socket.setEncoding(); // Convert to string the buffer
    socket.on("data", function (data) {
        var json = JSON.parse(data); // Convert to JSON the petition of the client  
        var validOptionPattern = /^[1-5]$/;
        if (json.action.search(validOptionPattern) != -1) {
            var client = initDBClient(); // Initialize the database connection 
            switch (parseInt(json.action)) {
            case 1: // Creating a new account
                client.query('INSERT INTO accounts VALUES(NULL,0)', function (error, result) {
                    if (error) {
                        logger.log('error', 'At inserting a new account DB is down: ' + error.message);
                        client.end();
                        var response = {
                            account: 'Error al insertar una nueva cuenta',
                            quantity: 0,
                            error: true
                        };
                    } else {
                        logger.log('info', 'New account was created with id: ' + result.insertId)
                        var response = {
                            account: result.insertId,
                            quantity: 0,
                            error: false
                        };
                    }
                    resultJson = JSON.stringify(response);
                    logger.log('info', 'Answer sent at inserting a new account');
                    socket.write(resultJson);
                });
                break;
            case 2: // Checking the balance of an account 
                client.query('SELECT * FROM accounts WHERE number_account = ?', [parseInt(json.account)], function selectAccount(err, results, fields) {
                    if (err) {
                        logger.log('error', 'At check balance: ' + err.message);
                        client.end();
                        var response = {
                            account: 'Error al consultar saldo',
                            quantity: 0,
                            error: true
                        };
                    } else {
						if(results == 0){
							logger.log('error', 'Balance inquiry: account does not exist');
							var response = {
                            account: 'Error al consultar saldo',
                            quantity: 0,
                            error: true
                        	};
						}
						else{
		                    logger.log('info', 'Balance inquiry: success for id ' + results[0].number_account)						
		                    var response = {
		                        account: results[0].number_account,
		                        quantity: results[0].balance,
		                        error: false
		                    };
						}
                    }
                    resultJson = JSON.stringify(response);
                    logger.log('info', 'Answer sent at check balance');					
                    socket.write(resultJson);
                });
                break;
            case 3: // Deposit for an account
				var amount = parseInt(json.quantity);
				var account_number = parseInt(json.account);			
                client.query('UPDATE accounts SET balance = balance + ? WHERE number_account = ?', [amount, account_number], function updateAccount(err, results, fields) {			
                    if (err) {
                        logger.log('error', 'Deposit: ' + err.message);
                        client.end();											
                        var response = {
                            account: 'Error at deposit: ' + err.message,
                            quantity: 0,
                            error: true
                        };
                    } else if (results.affectedRows == 0){
						logger.log('error', 'Deposit: account does not exist');
						var response = {
		                    account: 'Error al depositar la cuenta no existe',
		                    quantity: 0,
		                    error: true
                    	};
                    }
					else{
						var response = {
		                    account: 'Deposito exitoso para la cuenta: ' + account_number,
		                    quantity: 0,
		                    error: false
                    	};
					}
					resultJson = JSON.stringify(response);							
				    logger.log('info', 'Answer sent');
				    socket.write(resultJson);			
                });
					
				break;			
				
				/*logger.log('info', 'Deposit: success for id ' + account_number);
				client.query('SELECT * FROM accounts WHERE number_account = ?', account_number, function selectAccount(err, results, fields) {
					console.log("balance in deposit");
                        if (err) {
                            logger.log('error', 'Check balance (in deposit): ' + err.message);
                            client.end();
                            var response = {
                                account: 'Error at balance inquiry (in deposit): ' + err.message,
                                quantity: 0,
                                error: true
                            };
                        } else {
                            logger.log('info', 'Balance inquiry (in deposit): successful for id ' + account_number);
                            var response = {
                                account: account_number,
                                quantity: account_number,
                                error: false
                            };
                        }                       
            	});
				resultJson = JSON.stringify(response);							
	            logger.log('info', 'Answer sent');
	            socket.write(resultJson);
                break;*/
            case 4: // Withdraw from an account
				var amount = parseInt(json.quantity)
				var account_number = parseInt(json.account)
                client.query('UPDATE accounts SET balance = balance - ? WHERE number_account = ?', [amount, account_number], function updateAccount(err, results, fields) {
                    if (err) {
                        logger.log('error', 'Withdraw' + err.message);
                        client.end();
                        var response = {
                            account: 'Withdraw' + err.message,
                            quantity: 0,
                            error: true
                        };
                    } else if(results.affectedRows == 0){
						logger.log('error', 'Withdraw: account does not exist');
						var response = {
		                    account: 'Error al retirar dinero de la cuenta: '+ account_number,
		                    quantity: 0,
		                    error: true
                    	};
					}
                    else {
						logger.log('info', 'Withdraw: success for id ' + account_number);
						var response = {
		                    account: 'Retiro exitoso para la cuenta: ' + account_number,
		                    quantity: 0,
		                    error: false
                    	}; 
                    }
					resultJson = JSON.stringify(response);
                    logger.log('info', 'Answer sent for withraw');
                    socket.write(resultJson);
                });

				break;

				/*client.query('SELECT * FROM accounts WHERE number_account = ?', [parseInt(json.account)], function selectAccount(err, results, fields) {
                    if (err) {
                        logger.log('error', 'Balance inquiry (in withdraw): ' + err.message);
                        client.end();
                        var response = {
                            account: 'Error at balance inquiry (in withdraw): ' + err.message,
                            quantity: 0,
                            error: true
                        };
                    } else {
                        //logger.log('info', 'Balance inquiry (in withdraw): successful for id ' + results[0].number_account)
                        var response = {
                            account: "",//results[0].number_account,
                            quantity: "",//results[0].balance,
                            error: false
                        };
                    }                            
                });*/
				
            case 5: // Perform a Ping
                logger.log('info', 'Ping request arrived');
                var message = 'Ping Success!!! :)';
                var response = {
                    account: message,
                    quantity: 0,
                    error: false
                };
                resultJson = JSON.stringify(response);
                logger.log('info', 'Answer sent for ping');
                socket.write(resultJson);
                break;
            default:
                logger.log("error", "Imposible to reach, the option was: " + parseInt(json.action));
                break;
            }

            client.end();
        } else {logger.log('error', 'No action is performed');}
    });
	
    // Obtaining the address of the client 
	var remoteAddress = socket.remoteAddress
    socket.on('end', function () {
        logger.log('info', 'Client disconnected (ip,port) (' + socket.remoteAddress + ' , '+ socket.remotePort  + ')');
    });

    socket.on('error', function () {
        logger.log('error', 'Unhandled exeption on socket');
    });

});
// Starting the server at the port selected
server.listen(process.argv[2]);


function initDBClient() {
	var Client = require('mysql').Client,
        client = new Client();
    client.user = 'root';
    client.password = '';
    client.host = 'localhost';
    client.port = '3306';
    client.database = 'bank';

    client.on('error', function (error) {
		logger.log('error', 'Unhandled exception on DB');
	});
    return client;
}

